package com.hxtec.polaris.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.hxtec.polaris.commons.dto.PmsSearchParam;
import com.hxtec.polaris.commons.dto.PmsSearchSpuInfo;
import com.hxtec.polaris.commons.es.ElasticsearchTemplate;
import com.hxtec.polaris.mapper.ShopProductBaseMapper;
import com.hxtec.polaris.service.SearchService;
import io.searchbox.client.JestClient;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
import io.searchbox.core.Update;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Service
public class SearchServiceImpl implements SearchService {

    private ShopProductBaseMapper spuMapper;

    private ElasticsearchTemplate elasticsearchTemplate;

    private JestClient jestClient;

    private final RedisTemplate redisTemplate;


    public SearchServiceImpl(JestClient jestClient, ShopProductBaseMapper spuMapper, ElasticsearchTemplate elasticsearchTemplate, RedisTemplate redisTemplate) {
        this.jestClient=jestClient;
        this.spuMapper = spuMapper;
        this.elasticsearchTemplate = elasticsearchTemplate;
        this.redisTemplate = redisTemplate;
    }


    @Override
    public  Integer executeSpuElkScyn(){
        List<PmsSearchSpuInfo> spuList = spuMapper.getSpuInfo();
        List list=new ArrayList();
        spuList.forEach(spu->{
            boolean isSuccess = elasticsearchTemplate.save("hxtec", "spuList", spu.getSpu(), JSONObject.parseObject(JSONObject.toJSON(spu).toString()));
            if(isSuccess){
                list.add("success");
            }
        });
        return list.size();
    }


    @Override
    public boolean resetSpu(){
        Boolean flag=false;
        boolean isSuccess = elasticsearchTemplate.removeIndex("hxtec");
        if(isSuccess){
            flag=true;
        }
        return flag;
    }

    @Override
    public List<PmsSearchSpuInfo> searchInfo(PmsSearchParam searchParam) {
        String dslStr = getSearchDsl(searchParam);
        System.out.println(dslStr);
        // 用api执行复杂查询
        List<PmsSearchSpuInfo> pmsSearchSpuInfos = new ArrayList<>();
        Search search = new Search.Builder(dslStr).addIndex("hxtec").addType("spulist").build();
        SearchResult execute = null;
        try {
            execute = jestClient.execute(search);
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<SearchResult.Hit<PmsSearchSpuInfo, Void>> hits =new SearchResult(execute).getHits(PmsSearchSpuInfo.class);
        for (SearchResult.Hit<PmsSearchSpuInfo, Void> hit : hits) {
            PmsSearchSpuInfo source = hit.source;

            Map<String, List<String>> highlight = hit.highlight;
            if(highlight!=null){
                String skuName = highlight.get("skuName").get(0);
                source.setSkuName(skuName);
            }
            pmsSearchSpuInfos.add(source);
        }

        System.out.println(pmsSearchSpuInfos.size());
        return pmsSearchSpuInfos;
    }

    private String getSearchDsl(PmsSearchParam pmsSearchParam) {

        String[] skuAttrValueList = pmsSearchParam.getValueId();
        String keyword = pmsSearchParam.getKeyword();
        String catalogId = pmsSearchParam.getCategoryId();

        // jest的dsl工具
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // bool
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        // filter
        if(StringUtils.isNotBlank(catalogId)){
            TermQueryBuilder termQueryBuilder = new TermQueryBuilder("categoryId",catalogId);
            boolQueryBuilder.filter(termQueryBuilder);
        }
        // must
        if(StringUtils.isNotBlank(keyword)){
            MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("skuName",keyword);
            boolQueryBuilder.must(matchQueryBuilder);
        }

        // query
        searchSourceBuilder.query(boolQueryBuilder);

        // highlight
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<span style='color:red;'>");
        highlightBuilder.field("skuName");
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);
        // sort
        searchSourceBuilder.sort("hotScore", SortOrder.DESC);
        // from
        searchSourceBuilder.from(0);
        // size
        searchSourceBuilder.size(20);


        // aggs
//        TermsAggregationBuilder groupby_attr = AggregationBuilders.terms("groupby_attr").field("skuAttrValueList.valueId");
//        searchSourceBuilder.aggregation(groupby_attr);


        return searchSourceBuilder.toString();

    }

}
